package com.agrm.member.interceptor;

import com.agrm.model.common.dtos.ResponseResult;
import com.agrm.model.common.enums.AppHttpCodeEnum;
import com.agrm.utils.JwtUtil;
import com.alibaba.fastjson2.JSON;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.PrintWriter;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

/**
 * @Author 22:30Plane
 * @Version 1.0.0
 * <p>
 * created by 22:30Plane on 2025/8/14, last modified by 22:30Plane on 2025/8/14
 */
@Component
public class JwtInterceptor implements HandlerInterceptor {

    @Value("${jwt.secretKey}")
    private String secretKey;

    @Value("${jwt.refreshThreshold}") // 刷新阈值（分钟）
    private int refreshThreshold;

    private boolean shouldRefresh(Date expiresAt) {
        if (expiresAt == null) {
            return false;
        }

        long currentTime = System.currentTimeMillis();
        long expireTime = expiresAt.getTime();
        long thresholdMillis = (long) refreshThreshold * 60 * 1000;

        return (expireTime - currentTime) < thresholdMillis;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String jwt = request.getHeader("Authorization");
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secretKey)).build();
        try{
            DecodedJWT verify = verifier.verify(jwt);
            Date expiresAt = verify.getExpiresAt();
            if (shouldRefresh(expiresAt)) {
                String newJwt = JwtUtil.createJwt(
                        verify.getClaim("username").asString(),
                        UUID.randomUUID().toString(),
                        Map.of(
                                "id", verify.getClaim("userId").asString(),
                                "username", verify.getClaim("username").asString()
                        ),
                        LocalDateTime.now().plusMinutes(30),
                        secretKey
                );
                response.setHeader("token", newJwt);
            }
            return true;
        } catch (JWTVerificationException e) {
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            response.setContentType("application/json;charset=utf-8");
            PrintWriter writer = response.getWriter();
            writer.write(JSON.toJSONString(ResponseResult.errorResult(AppHttpCodeEnum.TOKEN_INVALID)));
            writer.flush();
            return false;
        }
    }
}